/* 
 * processFunctions.cpp
 *
 *  Created on: 10/04/2014
 *      Author: Emiliano R. Gudino
 */

#include "Process_Functions.h"

// Define for each command his function
char Init_Functions_Ptr_Array(ptr_functions_type ptr_functions[TOTAL_CMDS_FUNCTIONS])
{
	ptr_functions[CLS] = Process_Default;
	ptr_functions[ESE] = Process_Default;
	ptr_functions[ESE_QM] = Process_Default;
	ptr_functions[ESR_QM] = Process_Default;
	ptr_functions[IDN_QM] = Process_IdnQM;
	ptr_functions[OPC] = Process_Default;
	ptr_functions[OPC_QM] = Process_Default;
	ptr_functions[RST] = Process_Default;
	ptr_functions[SRE] = Process_Default;
	ptr_functions[SRE_QM] = Process_Default;
	ptr_functions[STB_QM] = Process_Default;
	ptr_functions[TST_QM] = Process_Default;
	ptr_functions[WAI] = Process_Default;

	ptr_functions[SYST_ERROR_QM] = Process_Default;
	ptr_functions[SYST_VERS_QM] = Process_Default;

	ptr_functions[STAT_OPER_QM] = Process_Default;
	ptr_functions[STAT_OPER_COND_QM] = Process_Default;
	ptr_functions[STAT_OPER_ENAB] = Process_Default;
	ptr_functions[STAT_OPER_ENAB_QM] = Process_Default;
	ptr_functions[STAT_QUES_QM] = Process_Default;
	ptr_functions[STAT_QUES_COND_QM] = Process_Default;
	ptr_functions[STAT_QUES_ENAB] = Process_Default;
	ptr_functions[STAT_QUES_ENAB_QM] = Process_Default;
	ptr_functions[STAT_PRES] = Process_Default;

	ptr_functions[OUTP] = Process_Default;

	ptr_functions[SOUR_VOLT_ACn] = Process_Volt;
	ptr_functions[SOUR_CURR_LIMn] = Process_Default;
	ptr_functions[SOUR_FREQn] = Process_Default;
	ptr_functions[SOUR_RAMPn] = Process_Default;
	ptr_functions[SOUR_PHASn] = Process_Default;
	ptr_functions[SOUR_WAVEFORMn] = Process_Default;

	ptr_functions[SOUR_VOLT_ACn_QM] = Process_Default;
	ptr_functions[SOUR_CURR_LIMn_QM] = Process_Default;
	ptr_functions[SOUR_FREQn_QM] = Process_Default;
	ptr_functions[SOUR_RAMPn_QM] = Process_Default;
	ptr_functions[SOUR_PHASn_QM] = Process_Default;
	ptr_functions[SOUR_WAVEFORMn_QM] = Process_Default;

	ptr_functions[MEAS_VOLT_RMSn_QM] = Process_Meas_Volt;
	ptr_functions[MEAS_VLLn_QM] = Process_Meas_Volt;
	ptr_functions[MEAS_FREQn_QM] = Process_Meas_Volt;
	ptr_functions[MEAS_CURR_RMSn_QM] = Process_Meas_Volt;
	ptr_functions[MEAS_CURR_PEAKn_QM] = Process_Meas_Volt;
	ptr_functions[MEAS_CURR_RESTn_QM] = Process_Meas_Volt;
	ptr_functions[MEAS_POWn_QM] = Process_Meas_Volt;
	ptr_functions[MEAS_KVAn_QM] = Process_Meas_Volt;
	ptr_functions[MEAS_PFn_QM] = Process_Meas_Volt;

	ptr_functions[SOUR_VOLT_DCn] = Process_Default;
	ptr_functions[SOUR_VOLT_DCn_QM] = Process_Default;
	ptr_functions[MEAS_VOLT_DCn_QM] = Process_Meas_Volt;
	ptr_functions[MEAS_VOLT_ACn_QM] = Process_Meas_Volt;
	ptr_functions[MEAS_CURR_DCn_QM] = Process_Meas_Volt;
	ptr_functions[MEAS_CURR_ACn_QM] = Process_Meas_Volt;

	ptr_functions[ERR_TOO_MANY_NUM_SUF] = Process_Error;
	ptr_functions[ERR_NO_COMMAND] = Process_Error;
	ptr_functions[ERR_NUM_SUF_INVALID] = Process_Error;
	ptr_functions[ERR_INVALID_VALUE] = Process_Error;
	ptr_functions[ERR_INVALID_DIMS] = Process_Error;
	ptr_functions[ERR_PARAM_OVERFLOW] = Process_Error;
	ptr_functions[ERR_PARAM_UNITS] = Process_Error;
	ptr_functions[ERR_PARAM_TYPE] = Process_Error;
	ptr_functions[ERR_PARAM_COUNT] = Process_Error;
	ptr_functions[ERR_UNMATCHED_QUOTE] = Process_Error;
	ptr_functions[ERR_UNMATCHED_BRACKET] = Process_Error;
	ptr_functions[ERR_INVALID_CMD] = Process_Error;
	ptr_functions[ERR_NO_ENTRY] = Process_Error;
	ptr_functions[ERR_TOO_MANY_DIMS] = Process_Error;

	return SUCCESS;
}

char Process_Default(command_request_str * command, command_response_str * responseBuff)
{
	responseBuff->response_type = RESPONSE_OK;
	// bzero((char *)responseBuff->response, MAX_PARAM_LENGTH); // not needed
	return SUCCESS;
}

// This function is temporal, in the future it will be implemented in accordance with the SCPI standard, probably in a different file
char Process_Error(command_request_str * command, command_response_str * responseBuff)
{
	string response = "Error: ";
	switch (command->command_id)
	{
	case ERR_TOO_MANY_NUM_SUF:
		response += "DESIGN ERROR: Too many numeric suffices in Command Spec";
		break;
	case ERR_NO_COMMAND:
		response += "No Input Command to parse";
		break;
	case ERR_NUM_SUF_INVALID:
		response += "Numeric suffix is invalid value";
		break;
	case ERR_INVALID_VALUE:
		response += "Invalid value in numeric or channel list, e.g. out of range";
		break;
	case ERR_INVALID_DIMS:
		response += "Invalid number of dimensions in a channel list";
		break;
	case ERR_PARAM_OVERFLOW:
		response += "Parameter of type Numeric Value overflowed its storage";
		break;
	case ERR_PARAM_UNITS:
		response += "Wrong units for parameter";
		break;
	case ERR_PARAM_TYPE:
		response += "Wrong type of parameter(s)";
		break;
	case ERR_PARAM_COUNT:
		response = "Wrong number of parameters";
		break;
	case ERR_UNMATCHED_QUOTE:
		response += "Unmatched quotation mark (single/double) in parameters";
		break;
	case ERR_UNMATCHED_BRACKET:
		response += "Unmatched bracket";
		break;
	case ERR_INVALID_CMD:
		response += "Command keywords were not recognized";
		break;
	case ERR_NO_ENTRY:
		response += "No entry in list to retrieve (number list or channel list)";
	case ERR_TOO_MANY_DIMS:
		response += "Too many dimensions in entry to be returned in parameters";
		break;
	}
	responseBuff->response_type = RESPONSE_STRING;
	strcpy(responseBuff->response, response.c_str());						// Assign the response
	return SUCCESS;
}

char Process_Volt(command_request_str * command, command_response_str * responseBuff)
{
	printf("Command: VOLT%d %f\n", command->command_suffix, *(double *)command->arguments);	// for debugging only‏

	// Change RMS voltage here

	responseBuff->response_type = RESPONSE_OK;
	return SUCCESS;
}

char Process_IdnQM(command_request_str * command, command_response_str * responseBuff)
{
	printf("Command: *IDN?\n");												// for debugging only
	string response = "<" + (string) SCPI_MANUFACTURER + "," + (string) SCPI_DEV_NAME + "," + (string) SCPI_DEV_VERSION + "," + (string) SCPI_DEV_ASSEMBLY + ">";	// for debugging only

	// load desired *IDN data from OD and store it in a string "response"

	strcpy(responseBuff->response, response.c_str());

	responseBuff->response_type = RESPONSE_STRING;
	return SUCCESS;
}

char Process_Meas_Volt(command_request_str * command, command_response_str * responseBuff)
{
	printf("Command: MEAS:VOLT%d?\n", command->command_suffix);				// for debugging only
	double voltage_measurement = ((double)(rand() % 100000)) / 1000;		// for debugging only

	// Read RMS voltage here and store it in a double "voltage_measurement"

	*((double *)responseBuff->response) = voltage_measurement;

	responseBuff->response_type = RESPONSE_ONE_DOUBLE;
	return SUCCESS;
}
